package com.ymh.service.impl;

import com.ymh.dao.ResourceDAO;
import com.ymh.dao.RoleDAO;
import com.ymh.dao.RoleResourceDAO;
import com.ymh.dao.UserDAO;
import com.ymh.dao.UserRoleDAO;
import com.ymh.domain.RoleDO;
import com.ymh.domain.RoleResourceDO;
import com.ymh.domain.UserDO;
import com.ymh.domain.UserDetailsDTO;
import com.ymh.domain.UserDetailsDTO.CustomAuthority;
import com.ymh.domain.UserRoleDO;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * @author: 13590
 * @date: 2020/11/7 11:21
 * @description:
 */
@Service
public class UserDetailServiceImpl implements UserDetailsService {

  @Autowired
  private UserDAO UserDAO;
  @Autowired
  private UserRoleDAO userRoleDAO;
  @Autowired
  private RoleDAO roleDAO;
  @Autowired
  private RoleResourceDAO roleResourceDAO;
  @Autowired
  private ResourceDAO resourceDAO;

  @Override
  public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    //获取本地用户
    Optional<UserDO> userOptional = UserDAO.findOne(Example.of(new UserDO().setUsername(userName)));
    UserDO user = userOptional
        .orElseThrow(() -> new UsernameNotFoundException("用户[" + userName + "]不存在"));
    Integer userId = user.getId();

    UserDetailsDTO userDetailsDTO = new UserDetailsDTO();
    BeanUtils.copyProperties(user, userDetailsDTO);
    List<UserRoleDO> userRoles = userRoleDAO
        .findAll(Example.of(new UserRoleDO().setUserId(userId)));
    List<GrantedAuthority> authorities = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(userRoles)) {
      List<RoleDO> roles = roleDAO
          .findAllById(userRoles.stream().map(UserRoleDO::getRoleId).collect(Collectors.toSet()));
      roles.forEach(roleDO -> authorities.add(new CustomAuthority(roleDO.getName())));

      List<String> resourceUrls = roleResourceDAO
          .getResourceUrlByRoleId(roles.stream().map(RoleDO::getId).collect(Collectors.toList()));

      if(CollectionUtils.isNotEmpty(resourceUrls)){
        resourceUrls.forEach(resourceUrl -> authorities.add(new CustomAuthority(resourceUrl)));
      }
    }
    authorities.add(new CustomAuthority("ROLE_ADMIN"));
    userDetailsDTO.setAuthorities(authorities);
    //返回oauth2的用户
    return userDetailsDTO;
  }
}
